home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------
- membug.c
- Demonstrate MSC malloc() large size problem
-
- Description
-
- membug.c demonstrates a problem that occurs when Microsoft C,
- version 5.10 is used to allocate and free large blocks of
- memory.
-
- If this program is compiled and run, you will find
- that the first list will have significantly more memory
- allocated to it. The second list will only have 1 to 2
- elements allocated to it, depending on your memory layout.
-
- The basic problem is that MSC never deallocates a DOS
- allocated memory block, even if the memory call is about to
- fail. Thus, the first list causes the MSC runtime to allocate
- memory in 48K blocks. When the first list is freed, the
- 48K blocks remain. Then, when the second list is allocated,
- there are only 2 blocks that DOS can carve the 60K blocks
- from: the default memory segment and the last DOS memory block.
- The default memory segment is 64K, so we should always get
- an allocation from it. The last memory block can be expanded
- by DOS to fit the 60K request if your memory layout will allow
- it.
-
- Note that if you reverse the order of memory requests, both
- will return the same number of memory blocks because the 48K
- requests will fit in the 60K blocks.
-
- Compilation
-
- Compilation is under Microsoft C, verison 5.1 using the command:
-
- c1 /W3 /AL membug.c
-
- Execution
-
- Execution of the program should use the command line:
-
- membug > membug.out
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <dos.h>
-
- /* Local definitions */
- /* ----------------- */
- #define FIRST_ALLOC_SIZE 48000
- #define SECOND_ALLOC_SIZE 60000
-
- /* Memory allocation list structure */
- /* -------------------------------- */
- typedef struct mb /* Memory list node */
- { /* ---------------------------- */
- struct mb * mb_next ; /* Pointer to next block */
- char mb_data ; /* Start of data area */
- /* Actual data area size is */
- /* determined by runtime */
- /* malloc() argument */
- } MEM_BLOCK ;
-
- /* Pointer conversion macros */
- /* ------------------------- */
- #define FARPTR_SEG(a) ((int) (((unsigned long) (a)) >> 16))
- #define FARPTR_OFF(a) ((int) ((long) (a)))
- #define MAKE_FARPTR(seg,off) ((void far *) ((((long) (seg)) << 16) + (off)))
-
- /* Function prototypes */
- /* ------------------- */
- void main() ;
- void DOS_Mem_Display(char *) ;
-
- /*------------------------------------------------------------------------
-
- main
- Entry point for MSC dynamic memory test
-
- Usage
-
- void
- main()
-
- Parameters
-
- None
-
- Description
-
- main() is the entry point for the Microsoft C dynamic memory
- test. The function allocates a list of FIRST_ALLOC_SIZE
- elements, frees the first list, allocates a second
- list of SECOND_ALLOC_SIZE, and frees the second list. The
- statistics printed out are the total bytes allocated by each
- allocation and a dump of the DOS memory list after each
- allocation/free.
-
- Notes
-
- None
- */
-
- void
-
-
- main()
- {
- MEM_BLOCK * list ;
- MEM_BLOCK * p ;
- long first_size ;
- long second_size ;
-
- /* Allocate list using first allocation size */
- /* ----------------------------------------- */
- list = NULL ;
- first_size = 0 ;
- while ((p = (MEM_BLOCK *) malloc(FIRST_ALLOC_SIZE)) != NULL)
- {
- p->mb_next = list ;
- list = p ;
- first_size += FIRST_ALLOC_SIZE ;
- }
-
- /* Print first allocation results */
- /* ------------------------------ */
- printf("***** First allocation - %ld *****\n\n", first_size) ;
- DOS_Mem_Display("After first allocation\n") ;
-
- /* Free first